package com.tencent.wxcloudrun.service.impl;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencent.wxcloudrun.constant.RedisKeyConstant;
import com.tencent.wxcloudrun.domain.TActi;
import com.tencent.wxcloudrun.enums.ActiBlackStatEnum;
import com.tencent.wxcloudrun.enums.ActiSelectedStatEnum;
import com.tencent.wxcloudrun.enums.ActiStatEnum;
import com.tencent.wxcloudrun.exception.BusinessException;
import com.tencent.wxcloudrun.mapper.TActiMapper;
import com.tencent.wxcloudrun.service.TActiService;
import com.tencent.wxcloudrun.util.DateUtils;
import com.tencent.wxcloudrun.util.RedisUtil;
import com.tencent.wxcloudrun.vo.request.acti.ActiAddReqVo;
import com.tencent.wxcloudrun.vo.request.acti.ActiUpdateReqVo;

import lombok.extern.slf4j.Slf4j;

/**
 * @author ziyin.zhao
 * @description 针对表【t_acti(活动表)】的数据库操作Service实现
 * @createDate 2025-04-22 16:43:56
 */
@Slf4j
@Service
public class TActiServiceImpl extends ServiceImpl<TActiMapper, TActi> implements TActiService {

    @Resource
    private RedisUtil redisUtil;

    @Override
    public Long add(ActiAddReqVo reqVo) {
        TActi acti = new TActi();
        acti.setActiType(reqVo.getActiType());
        acti.setActiStatus(ActiStatEnum.DRAFT.getValue());
        acti.setActiSelectedStatus(ActiSelectedStatEnum.NOT_BEGIN.getValue());
        acti.setActiBlackStatus(ActiBlackStatEnum.NOT_BEGIN.getValue());
        acti.setActiTitle(reqVo.getActiTitle());
        acti.setActiContent(reqVo.getActiContent());
        acti.setActiImgUrlList(reqVo.getActiImgUrlList());
        acti.setActiJoinType(reqVo.getActiJoinType());
        acti.setActiDate(reqVo.getActiDate());
        acti.setActiBeginTime(LocalDateTime.parse(reqVo.getActiBeginTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setActiEndTime(LocalDateTime.parse(reqVo.getActiEndTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setSelectedFlag(reqVo.getSelectedFlag());
        acti.setSelectedJoinType(reqVo.getSelectedJoinType());
        acti.setSelectedCount(reqVo.getSelectedCount());
        acti.setSelectedBeginTime(
            LocalDateTime.parse(reqVo.getSelectedBeginTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setSelectedEndTime(LocalDateTime.parse(reqVo.getSelectedEndTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setPreSaleFlag(reqVo.getPreSaleFlag());
        acti.setFormFlag(reqVo.getFormFlag());
        acti.setBlackFlag(reqVo.getBlackFlag());
        acti.setBlackCount(reqVo.getBlackCount());
        acti.setBlackBeginTime(LocalDateTime.parse(reqVo.getBlackBeginTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setBlackEndTime(LocalDateTime.parse(reqVo.getBlackEndTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setCreatedTime(LocalDateTime.now());
        acti.setUpdatedTime(LocalDateTime.now());
        acti.setCreatedBy(String.valueOf(reqVo.getUserId()));
        acti.setUpdatedBy(String.valueOf(reqVo.getUserId()));
        this.save(acti);
        return acti.getId();
    }

    @Override
    public void update(ActiUpdateReqVo reqVo) {
        TActi acti = this.getById(reqVo.getActiId());
        if (Objects.isNull(acti)) {
            log.error("更新活动-活动不存在-活动ID={}", reqVo.getActiId());
            throw new BusinessException("活动不存在");
        }
        acti.setActiType(reqVo.getActiType());
        acti.setActiTitle(reqVo.getActiTitle());
        acti.setActiContent(reqVo.getActiContent());
        acti.setActiImgUrlList(reqVo.getActiImgUrlList());
        acti.setActiJoinType(reqVo.getActiJoinType());
        acti.setActiDate(reqVo.getActiDate());
        acti.setActiBeginTime(LocalDateTime.parse(reqVo.getActiBeginTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setActiEndTime(LocalDateTime.parse(reqVo.getActiEndTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setSelectedFlag(reqVo.getSelectedFlag());
        acti.setSelectedJoinType(reqVo.getSelectedJoinType());
        acti.setSelectedCount(reqVo.getSelectedCount());
        acti.setSelectedBeginTime(
            LocalDateTime.parse(reqVo.getSelectedBeginTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setSelectedEndTime(LocalDateTime.parse(reqVo.getSelectedEndTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setPreSaleFlag(reqVo.getPreSaleFlag());
        acti.setFormFlag(reqVo.getFormFlag());
        acti.setBlackFlag(reqVo.getBlackFlag());
        acti.setBlackCount(reqVo.getBlackCount());
        acti.setBlackBeginTime(LocalDateTime.parse(reqVo.getBlackBeginTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setBlackEndTime(LocalDateTime.parse(reqVo.getBlackEndTime(), DateUtils.LOCAL_DATE_TIME_FORMATTER));
        acti.setUpdatedTime(LocalDateTime.now());
        acti.setUpdatedBy(String.valueOf(reqVo.getUserId()));
        this.updateById(acti);
    }

    @Override
    public void delete(Long userId, Long actiId) {
        LambdaUpdateWrapper<TActi> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(TActi::getDeleteFlag, 1);
        wrapper.set(TActi::getEnableFlag, 0);
        wrapper.set(TActi::getUpdatedTime, LocalDateTime.now());
        wrapper.set(TActi::getUpdatedBy, userId);
        wrapper.eq(TActi::getId, actiId);
        this.update(wrapper);
    }

    @Override
    public void release(Long userId, Long actiId) {
        LambdaUpdateWrapper<TActi> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(TActi::getActiStatus, ActiStatEnum.NOT_BEGIN.getValue());
        wrapper.set(TActi::getUpdatedTime, LocalDateTime.now());
        wrapper.set(TActi::getUpdatedBy, userId);
        wrapper.eq(TActi::getId, actiId);
        this.update(wrapper);
    }

    @Override
    public void actiBegin(Long actiId) {
        TActi acti = this.getById(actiId);
        if (Objects.isNull(acti)) {
            log.error("活动开始-活动不存在-活动ID={}", actiId);
            throw new BusinessException("活动不存在");
        }
        acti.setActiStatus(ActiStatEnum.IN_PROGRESS.getValue());
        acti.setUpdatedTime(LocalDateTime.now());
        this.updateById(acti);
    }

    @Override
    public void actiEnd(Long actiId) {
        TActi acti = this.getById(actiId);
        if (Objects.isNull(acti)) {
            log.error("活动结束-活动不存在-活动ID={}", actiId);
            throw new BusinessException("活动不存在");
        }
        acti.setActiStatus(ActiStatEnum.ALREADY_END.getValue());
        acti.setUpdatedTime(LocalDateTime.now());
        this.updateById(acti);
    }

    @Override
    public void actiSelectedBegin(Long actiId) {
        TActi acti = this.getById(actiId);
        if (Objects.isNull(acti)) {
            log.error("活动开始-活动不存在-活动ID={}", actiId);
            throw new BusinessException("活动不存在");
        }
        acti.setActiSelectedStatus(ActiSelectedStatEnum.IN_PROGRESS.getValue());
        acti.setUpdatedTime(LocalDateTime.now());
        this.updateById(acti);
    }

    @Override
    public void actiSelectedEnd(Long actiId) {
        TActi acti = this.getById(actiId);
        if (Objects.isNull(acti)) {
            log.error("活动开始-活动不存在-活动ID={}", actiId);
            throw new BusinessException("活动不存在");
        }
        acti.setActiSelectedStatus(ActiSelectedStatEnum.ALREADY_END.getValue());
        acti.setUpdatedTime(LocalDateTime.now());
        this.updateById(acti);
    }

    @Override
    public void actiBlackBegin(Long actiId) {
        TActi acti = this.getById(actiId);
        if (Objects.isNull(acti)) {
            log.error("活动开始-活动不存在-活动ID={}", actiId);
            throw new BusinessException("活动不存在");
        }
        acti.setActiBlackStatus(ActiBlackStatEnum.IN_PROGRESS.getValue());
        acti.setUpdatedTime(LocalDateTime.now());
        this.updateById(acti);
    }

    @Override
    public void actiBlackEnd(Long actiId) {
        TActi acti = this.getById(actiId);
        if (Objects.isNull(acti)) {
            log.error("活动开始-活动不存在-活动ID={}", actiId);
            throw new BusinessException("活动不存在");
        }
        acti.setActiBlackStatus(ActiBlackStatEnum.ALREADY_END.getValue());
        acti.setUpdatedTime(LocalDateTime.now());
        this.updateById(acti);
    }

    @Override
    public void joinCheck(Long actiId) {
        String actiStatus = redisUtil.get(RedisKeyConstant.getActiStatusRedisKey(actiId));
        if (!StringUtils.hasLength(actiStatus)
            || !actiStatus.equals(String.valueOf(ActiStatEnum.IN_PROGRESS.getValue()))) {
            log.error("用户参选-活动状态不为进行中-活动状态={}", actiStatus);
            throw new BusinessException("活动还未开始 请稍后再试");
        }
    }

    @Override
    public void joinSelectedCheck(Long actiId) {
        String actiSelectedStatus = redisUtil.get(RedisKeyConstant.getActiSelectedStatusRedisKey(actiId));
        if (!StringUtils.hasLength(actiSelectedStatus)) {
            log.error("用户参选-该活动不支持入围活动-活动状态={}", actiSelectedStatus);
            throw new BusinessException("该活动不支持入围活动");
        }
        if (actiSelectedStatus.equals(String.valueOf(ActiSelectedStatEnum.NOT_BEGIN.getValue()))) {
            log.error("用户参选-入围活动还未开始-活动状态={}", actiSelectedStatus);
            throw new BusinessException("入围活动还未开始 请稍后再试");
        }
        if (actiSelectedStatus.equals(String.valueOf(ActiSelectedStatEnum.ALREADY_END.getValue()))) {
            log.error("用户参选-入围活动已经结束-活动状态={}", actiSelectedStatus);
            throw new BusinessException("入围活动已经结束");
        }
    }

    @Override
    public void joinBlackCheck(Long actiId) {
        String actiBlackStatus = redisUtil.get(RedisKeyConstant.getActiBlackStatusRedisKey(actiId));
        if (!StringUtils.hasLength(actiBlackStatus)) {
            log.error("用户参选-该活动不支持黑箱卡-活动状态=={}", actiBlackStatus);
            throw new BusinessException("该活动不支持黑箱卡");
        }
        if (actiBlackStatus.equals(String.valueOf(ActiBlackStatEnum.NOT_BEGIN.getValue()))) {
            log.error("用户参选-黑箱活动还未开始-活动状态={}", actiBlackStatus);
            throw new BusinessException("黑箱活动还未开始 请稍后再试");
        }
        if (actiBlackStatus.equals(String.valueOf(ActiBlackStatEnum.ALREADY_END.getValue()))) {
            log.error("用户参选-黑箱活动已经结束-活动状态={}", actiBlackStatus);
            throw new BusinessException("黑箱活动已经结束");
        }
    }

    @Override
    public List<TActi> listActi(Integer actiStatus, String actiTitle) {
        LambdaQueryWrapper<TActi> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(actiStatus != null, TActi::getActiStatus, actiStatus);
        if (StringUtils.hasLength(actiTitle)) {
            queryWrapper.like(TActi::getActiTitle, actiTitle);
        }
        queryWrapper.eq(TActi::getEnableFlag, 1);
        queryWrapper.orderByDesc(TActi::getActiDate, TActi::getActiBeginTime);
        return this.list(queryWrapper);
    }
}
